Logging
support in the cloud is one of the biggest concerns of the developer
community. With highly interactive integrated design environment (IDE)
tools like Visual Studio.NET and runtime environments like the .NET
Framework, you can pinpoint problems in you code even in deployed
environments when applications are running on-premise. However, the
Visual Studio.NET domain is limited to the access it has to the
application's runtime environment. Visual Studio.NET communicates with
the runtime environment of the application to gather debug information
of the application. The application needs to have debug symbols loaded
in runtime for Visual Studio.NET to debug. The Windows Azure
development fabric has access to the local runtime environment, so you
can debug your local Windows Azure application like any other .NET
application by adding breakpoints.
Unfortunately, the
Windows Azure cloud environment is inaccessible to the local Visual
Studio.NET environment. Once the service is deployed to Windows Azure,
it is totally managed by Windows Azure, and you do not have access to
its runtime. The Windows Azure team realized this and has added logging
capabilities to the Windows Azure runtime. The diagnostics service runs
along with your role instance, collects diagnostics data as per the
configuration, and can save the data to your Windows Azure storage
service if configured to do so. You can also communicate with the
diagnostics service remotely from an on-premise application or
configure it to persist the diagnostics data on a periodic basis. The
diagnostics service supports logging of the following data types from
your cloud service:
Windows Azure logs: These are the application logs that you dump from your application. These can be any messages emitted from your code.
Diagnostic monitor logs: These logs are about the diagnostics service itself.
Windows event logs: These are the Windows event logs generated on the machine on which the role instance is running.
Windows performance counters: These refer to the subscriptions to the performance counters on the machine on which the role instance is running
IIS logs and failed request traces: These are the IIS logs and the IIS failed request traces generated on the Web role instance.
Application crash dumps: These are the crash dumps generated when an application crashes.
The diagnostics gathering
model in Windows Azure consists of two fundamental steps—configuration
and management. In the configuration step, you configure the
diagnostics service with all the data types you are interested in
collecting the diagnostics information on, and then the diagnostics
service starts collecting the data for the configured data types
accordingly. In the management step, you use the diagnostics management
API provided by the Windows Azure SDK for changing the configuration of
an already running diagnostics service, and the diagnostics service
will reconfigure itself for collecting the appropriate data. You can
use the diagnostics management API from outside of the Windows Azure
cloud environment (e.g., on-premise) to interact with the diagnostics
service on your role instance. Next, using the same API, you can
perform scheduled or on-demand transfers of the diagnostics information
from role instance machines to your Windows Azure storage account.
In this book, I will focus
only on the Windows Azure logs data type, because it relates directly
to the development of Windows Azure services. I will provide some
examples of the rest of the data types, but will not be discussing
those in detail in this book. For more information on these data types,
please refer to the diagnostics API in Windows Azure SDK documentation.
The diagnostics API is present in the Microsoft.WindowsAzure.Diagnostics assembly.
1. Logging
Windows Azure Runtime API
consists of a managed code library and an unmanaged code library. In
this book, I will cover only the managed code library. The managed code
library namespace for diagnostics is Microsoft.WindowsAzure.Diagnostics. Associating diagnostics with you cloud service is a three step process:
Configure the trace listener.
Define the storage location for the diagnostics service.
Start the diagnostics service.
1.1. Configuring the Trace Listener
When you create a new role using the role templates template in Visual Studio.NET, the app.config and web.config files get created automatically in the role project and it consists of a trace listener provider, as shown in Listing 1.
Example 1. Diagnostics Trace Listener Configuration
<system.diagnostics> <trace> <listeners> <add type= "Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="AzureDiagnostics"> <filter type="" /> </add> </listeners> </trace> </system.diagnostics>
|
The DiagnosticMonitorTraceListener
enables you to use the .NET Tracing API for logging within the code.
You can use the Write() and WriteLine() methods of the
System.Diagnostics.Trace class for logging from your code as shown here:
Trace.WriteLine("INFORMATION LOG", "Information");
Trace.WriteLine("CRITICAL LOG", "Critical");
1.2. Defining the Storage Location for the Diagnostics Service
In the ServiceDefinition.csdef and ServiceConfiguration.cscfg
files, you have to define the diagnostics connection string pointing to
the storage location of your choice (development storage or cloud
storage). Visual Studio automatically generates this configuration for
you as shown in Listing 2.
Example 2. Diagnostics Connection String Configuration
For development storage: <ConfigurationSettings> <Setting name="DiagnosticsConnectionString" value = "UseDevelopmentStorage=true"/> </ConfigurationSettings> For cloud storage: <ConfigurationSettings> <Setting name="DiagnosticsConnectionString" value= "DefaultEndpointsProtocol=https;AccountName=proazurestorage;AccountKey=[YOURKEY]"/> </ConfigurationSettings>
|
1.3. Starting the Diagnostics Service
Next, you have to start the
diagnostics service in your role by passing in the connection string
name you defined in step 2. If you create a role using the Visual
Studio role templates, the WebRole.cs/WorkerRole.cs
files contain the code for starting the diagnostics service in the
OnStart() method,
DiagnosticMonitor.Start("DiagnosticsConnectionString");.
Once started, the
diagnostics monitoring service can start collecting the logged data.
You can also choose to further configure the diagnostics service
through the DiagnosticMonitorConfiguration class, as shown in Listing 3.
Example 3. Programmatically Changing the Diagnostics Configuration
//Get the default configuration DiagnosticMonitorConfiguration dmc = DiagnosticMonitor.GetDefault InitialConfiguration(); //Set the schedule to transfer logs every 10 mins to the storage dmc.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(10); //Start Diagnostics Monitor with the storage account configuration DiagnosticMonitor.Start("DiagnosticsConnectionString",dmc);
|
In Listing 3,
the diagnostics monitor is started with the configuration option to
transfer logs to the defined storage every 10 minutes automatically.
When designing cloud
applications, it is important to design diagnostics and logs reporting
right from the beginning. This will save you a lot of debugging time
and help you create a high quality application.